﻿namespace MvvmTools.NotifyPropertyChanged
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics.Contracts;
    using JetBrains.Annotations;

    /// <summary>
    /// Root observer container.
    /// </summary>
    /// <typeparam name="TProperty">
    /// Observable property type.
    /// </typeparam>
    internal sealed class RootNotificationListener<TProperty> : ChangeListener<TProperty>
        where TProperty : INotifyPropertyChanged
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RootNotificationListener{TProperty}"/> class.
        /// </summary>
        /// <param name="root">
        /// The root element.
        /// </param>
        internal RootNotificationListener([NotNull] TProperty root)
            : base(null, o => root, null)
        {
            Contract.Requires<ArgumentNullException>(!Equals(root, null));
        }

        /// <summary>
        /// Pass signal about change to root observer.
        /// </summary>
        /// <param name="source">
        /// The source of changes.
        /// </param>
        /// <param name="change">
        /// The information about changed property.
        /// </param>
        protected override void RaiseChangedToRoot(ChangeListenerBase source, PropertyChange change)
        {
            RaiseChangedToRootCompleted(source, change, source == this);
        }

        /// <summary>
        /// Get target object.
        /// </summary>
        /// <returns>
        /// Target object.
        /// </returns>
        protected override INotifyPropertyChanged GetObject()
        {
            return Getter(null);
        }
    }
}